package cn.baage.campus.service.impl;

import cn.baage.campus.mapper.CommentMapper;
import cn.baage.campus.model.dto.LoginUser;
import cn.baage.campus.model.po.Comment;
import cn.baage.campus.model.po.CommentImg;
import cn.baage.campus.model.po.User;
import cn.baage.campus.model.vo.CommentAddReqVO;
import cn.baage.campus.model.vo.CommentResVO;
import cn.baage.campus.service.CommentImgService;
import cn.baage.campus.service.CommentService;
import cn.baage.campus.service.UserService;
import cn.baage.campus.utils.DateUtils;
import cn.baage.campus.utils.MinioUtils;
import cn.baage.campus.utils.PageUtils;
import cn.baage.campus.utils.SecurityUtils;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 评论Service实现
 * @Author: 八阿哥
 * @url: baage.cn
 * @Version: 1.0
 **/
@Service
@RequiredArgsConstructor(onConstructor_ =@Autowired)
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    private final UserService userService;
    private final CommentImgService commentImgService;
    private final MinioUtils minioUtils;

    /**
     * 新增评论
     *
     * @param commentAddReqVO 评论信息
     */
    @Override
    @Transactional
    public void addComment(CommentAddReqVO commentAddReqVO) {
        String id = IdUtil.simpleUUID();
        Date now = new Date();
        LoginUser loginUser = SecurityUtils.getLoginUser();
        User userByDb = userService.getByUserName(loginUser.getUsername());
        Comment comment = BeanUtil.toBean(commentAddReqVO, Comment.class);
        comment.setId(id);
        comment.setUserId(loginUser.getId());
        comment.setCreateTime(now);
        comment.setUpdateTime(now);
        comment.setNickName(userByDb.getNickName());
        comment.setAvatarUrl(userByDb.getAvatarUrl());
        comment.setContent(comment.getContent().replace("\n", "<br>"));
        if (commentAddReqVO.getImgList() != null && !commentAddReqVO.getImgList().isEmpty()) {
            comment.setHaveImg(true);
            List<CommentImg> commentImgList = new ArrayList<>();
            for (String imgPath : commentAddReqVO.getImgList()) {
                CommentImg commentImg = new CommentImg();
                commentImg.setCommentId(id);
                commentImg.setImgPath(imgPath);
                commentImgList.add(commentImg);
            }
            commentImgService.saveBatch(commentImgList);
        }
        if (StrUtil.isNotBlank(commentAddReqVO.getReplyId()) && !"0".equals(commentAddReqVO.getReplyId())) {
            Comment replyComment = this.baseMapper.selectById(commentAddReqVO.getReplyId());
            comment.setReplyNickName(replyComment.getNickName());
        }
        this.baseMapper.insert(comment);
    }


    /**
     * 获取评论列表
     *
     * @param postingId 帖子ID
     * @return 评论列表
     */
    @Override
    public Map<String, Object> listComment(String postingId) {
        PageUtils.startPage();
        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Comment::getPostingId, postingId);
        queryWrapper.eq(Comment::getParentId, "0");
        queryWrapper.eq(Comment::getDelFlag, false);
        List<Comment> comments = this.baseMapper.selectList(queryWrapper);
        Long total = new PageInfo<Object>(comments).getTotal();
        ArrayList<CommentResVO> commentResList = new ArrayList<>();
        for (Comment comment : comments) {
            // 当前评论信息
            CommentResVO commentRes = BeanUtil.toBean(comment, CommentResVO.class);
            commentRes.setAvatarUrl(minioUtils.getAccessUrl(comment.getAvatarUrl()));
            commentRes.setTimeShow(DateUtils.formatTimeDifferenceNow(comment.getCreateTime()));
            if (comment.getHaveImg()) {
                commentRes.setImgList(getCommentImg(commentRes.getId()));
            }
            // 子评论信息
            List<CommentResVO> childComment = getChildComment(comment.getId());
            commentRes.setChildCommentList(childComment);
            commentResList.add(commentRes);
        }
        return new HashMap<String, Object>() {{
            put("total", total);
            put("rows", commentResList);
        }};
    }


    /**
     * 获取子评论信息
     *
     * @param commentId 评论ID
     */
    private List<CommentResVO> getChildComment(String commentId) {
        LambdaQueryWrapper<Comment> childQueryWrapper = new LambdaQueryWrapper<>();
        childQueryWrapper.eq(Comment::getParentId, commentId);
        childQueryWrapper.orderByAsc(Comment::getCreateTime);
        List<Comment> childCommentByDb = this.baseMapper.selectList(childQueryWrapper);
        List<CommentResVO> chileCommentList = new ArrayList<>();
        for (Comment childComment : childCommentByDb) {
            CommentResVO childCommentRes = BeanUtil.toBean(childComment, CommentResVO.class);
            childCommentRes.setAvatarUrl(minioUtils.getAccessUrl(childComment.getAvatarUrl()));
            childCommentRes.setTimeShow(DateUtils.formatTimeDifferenceNow(childComment.getCreateTime()));
            if (childComment.getHaveImg()) {
                childCommentRes.setImgList(getCommentImg(childCommentRes.getId()));
            }
            chileCommentList.add(childCommentRes);
        }
        return chileCommentList;
    }


    /**
     * 获取评论图片
     *
     * @param commentId 评论ID
     */
    private List<String> getCommentImg(String commentId) {
        List<String> imgList = commentImgService
                .listByCommentId(commentId).stream()
                .map(CommentImg::getImgPath).collect(Collectors.toList());
        return imgList.stream().map(minioUtils::getAccessUrl).collect(Collectors.toList());
    }

}
